Skip to content

Commit

Permalink
Add colour picker components (Graylog2#4626)
Browse files Browse the repository at this point in the history
* Add first version of ColorPicker component

* Add missing details of SelectPopover

* Add `ColorPickerPopover` component
  • Loading branch information
edmundoa authored and Marius Sturm committed Mar 2, 2018
1 parent 87a90ec commit d400729
Show file tree
Hide file tree
Showing 10 changed files with 215 additions and 2 deletions.
1 change: 1 addition & 0 deletions graylog2-web-interface/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
"opensans-npm-webfont": "^1.0.0",
"qs": "^6.3.0",
"react-ace": "^5.9.0",
"react-color": "^2.14.0",
"react-day-picker": "^5.0.0",
"react-dnd": "^2.0.2",
"react-dnd-html5-backend": "^2.0.0",
Expand Down
61 changes: 61 additions & 0 deletions graylog2-web-interface/src/components/common/ColorPicker.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import React from 'react';
import createReactClass from 'create-react-class';
import PropTypes from 'prop-types';
import { SwatchesPicker } from 'react-color';

/**
* Color picker component that let the user select a color from a list of 95 colors grouped by hue.
*/
const ColorPicker = createReactClass({
propTypes: {
/** Indicates the selected color in hexadecimal format. */
color: PropTypes.string,
/**
* Color palette in hexadecimal format. By default it uses the color palette defined by react-color,
* including 95 colors to pick from.
*/
colors: PropTypes.array,
/**
* Height of the color picker in pixels. By default it displays 2 rows of colors and the first color
* of the third row, indicating users that they can scroll through the list:
*
* `135px height per color row * 2 rows + 24px first color of 3rd row + 16px padding = 310px`
*
* You can set `Infinity` as `height` if you don't want the component to scroll.
*/
height: PropTypes.number,
/**
* Width of the color picker in pixels. By default it displays 5 columns of colors:
*
* `50px width per color column * 5 columns + 22px of padding = 272px`
*/
width: PropTypes.number,
/**
* Function that will be called when the selected color changes.
* The function receives the color in hexadecimal format as first
* argument and the event as the second argument.
*/
onChange: PropTypes.func.isRequired,
},

getDefaultProps() {
return {
color: undefined,
colors: undefined, // Use default color palette.
height: (135 * 2) + 24 + 16, // 135px color row * 2 rows + 24px first color 3rd row + 16px padding
width: (50 * 5) + 16 + 6, // 50px color columns * 5 columns + 22px padding
};
},

onColorChange(color, event) {
this.props.onChange(color.hex, event);
},

render() {
return (
<SwatchesPicker {...this.props} onChange={this.onColorChange} />
);
},
});

export default ColorPicker;
27 changes: 27 additions & 0 deletions graylog2-web-interface/src/components/common/ColorPicker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
```js
const createReactClass = require('create-react-class');

const ColorPickerExample = createReactClass({
getInitialState() {
return {
color: undefined,
};
},

handleColorChange(color) {
this.setState({ color: color });
},

render() {
const { color } = this.state;
return (
<div>
<p>{color ? `You picked ${color}.` : 'Pick a color'}</p>
<ColorPicker color={color} onChange={this.handleColorChange} />
</div>
);
},
});

<ColorPickerExample />
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
:local(.customPopover) .popover-content {
padding: 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React from 'react';
import createReactClass from 'create-react-class';
import PropTypes from 'prop-types';
import { OverlayTrigger, Popover } from 'react-bootstrap';
import { ColorPicker } from 'components/common';

import style from './ColorPickerPopover.css';

/**
* Component that renders a `ColorPicker` component inside a react bootstrap
* popover. This is meant to use in forms and UIs with limited space, as the color
* picker will only appear when the user interacts with the trigger node.
*
* This component will pass any additional props to `ColorPicker`, but their validation
* is left for that component. Please look at `ColorPicker`'s documentation for more
* information.
*/
const ColorPickerPopover = createReactClass({
propTypes: {
/** Provides an ID for this popover element. */
id: PropTypes.string.isRequired,
/** Indicates where the popover should appear. */
placement: PropTypes.oneOf(['top', 'right', 'bottom', 'left']),
/** Title to use in the popover header. */
title: PropTypes.string,
/** React node that will be used as trigger to show/hide the popover. */
triggerNode: PropTypes.node.isRequired,
/** Event that will show/hide the popover. */
triggerAction: PropTypes.oneOf(['click', 'hover', 'focus']),
},

getDefaultProps() {
return {
placement: 'bottom',
triggerAction: 'click',
title: 'Pick a color',
};
},

render() {
const { id, placement, title, triggerNode, triggerAction, ...colorPickerProps } = this.props;
const popover = (
<Popover id={id} title={title} className={style.customPopover}>
<ColorPicker {...colorPickerProps} />
</Popover>
);

return (
<OverlayTrigger trigger={triggerAction} placement={placement} overlay={popover} rootClose>
{triggerNode}
</OverlayTrigger>
);
},
});

export default ColorPickerPopover;
33 changes: 33 additions & 0 deletions graylog2-web-interface/src/components/common/ColorPickerPopover.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
```js
const createReactClass = require('create-react-class');
const { Button } = require('react-bootstrap');

const ColorPickerOverlayExample = createReactClass({
getInitialState() {
return {
color: undefined,
};
},

handleColorChange(color) {
this.setState({ color: color });
},

render() {
const { color } = this.state;

return (
<div>
<p>{color ? `You picked ${color}.` : 'Pick a color'}</p>
<ColorPickerPopover id="example-color-picker"
placement="right"
color={color}
triggerNode={<Button bsStyle="primary">Toggle color picker</Button>}
onChange={this.handleColorChange} />
</div>
);
},
});

<ColorPickerOverlayExample />
```
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,6 @@
}

:local(.dataFilterInput) {
margin-bottom: 0;
margin-bottom: 0 !important;
padding: 5px;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ import IsolatedScroll from 'react-isolated-scroll';

import style from './SelectPopover.css';

/**
* Component that displays a list of items in a popover and enable users to pick one of
* the options with the mouse. The component can (optionally) filter options with a text input
* and customize how items are displayed with a function.
*/
const SelectPopover = createReactClass({
propTypes: {
/** Provides an ID for this popover element. */
Expand Down
3 changes: 3 additions & 0 deletions graylog2-web-interface/src/components/common/index.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export { default as ClipboardButton } from './ClipboardButton';
export { default as ColorPicker } from './ColorPicker';
export { default as ColorPickerPopover } from './ColorPickerPopover';
export { default as ContentPackMarker } from './ContentPackMarker';
export { default as ControlledTableList } from './ControlledTableList';
export { default as DataTable } from './DataTable';
Expand All @@ -25,6 +27,7 @@ export { default as ReactGridContainer } from './ReactGridContainer';
export { default as SearchForm } from './SearchForm';
export { default as Select } from './Select';
export { default as SelectableList } from './SelectableList';
export { default as SelectPopover } from './SelectPopover';
export { default as SortableList } from './SortableList';
export { default as SortableListItem } from './SortableListItem';
export { default as SourceCodeEditor } from './SourceCodeEditor';
Expand Down
26 changes: 25 additions & 1 deletion graylog2-web-interface/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4991,7 +4991,7 @@ lodash.uniq@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"

lodash@^4.0.0:
lodash@^4.0.0, lodash@^4.0.1:
version "4.17.5"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511"

Expand Down Expand Up @@ -5088,6 +5088,10 @@ markdown@^0.5.0:
dependencies:
nopt "~2.1.1"

material-colors@^1.2.1:
version "1.2.5"
resolved "https://registry.yarnpkg.com/material-colors/-/material-colors-1.2.5.tgz#5292593e6754cb1bcc2b98030e4e0d6a3afc9ea1"

math-expression-evaluator@^1.2.14:
version "1.2.17"
resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz#de819fdbcd84dccd8fae59c6aeb79615b9d266ac"
Expand Down Expand Up @@ -6395,6 +6399,16 @@ react-codemirror2@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/react-codemirror2/-/react-codemirror2-2.0.2.tgz#68b2ae8923174a2b3d8b6fe905d0fd3c91d97d97"

react-color@^2.14.0:
version "2.14.0"
resolved "https://registry.yarnpkg.com/react-color/-/react-color-2.14.0.tgz#5828a11c034aa0939befbd888a066ee37d8c3cc2"
dependencies:
lodash "^4.0.1"
material-colors "^1.2.1"
prop-types "^15.5.10"
reactcss "^1.2.0"
tinycolor2 "^1.4.1"

react-day-picker@^5.0.0:
version "5.5.3"
resolved "https://registry.yarnpkg.com/react-day-picker/-/react-day-picker-5.5.3.tgz#d6a03bb0b15c6bb58629d749d8a7489cf6cfa52b"
Expand Down Expand Up @@ -6672,6 +6686,12 @@ react@^15.6.1:
object-assign "^4.1.0"
prop-types "^15.5.10"

reactcss@^1.2.0:
version "1.2.3"
resolved "https://registry.yarnpkg.com/reactcss/-/reactcss-1.2.3.tgz#c00013875e557b1cf0dfd9a368a1c3dab3b548dd"
dependencies:
lodash "^4.0.1"

read-pkg-up@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02"
Expand Down Expand Up @@ -7692,6 +7712,10 @@ tiny-emitter@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.0.2.tgz#82d27468aca5ade8e5fd1e6d22b57dd43ebdfb7c"

tinycolor2@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.1.tgz#f4fad333447bc0b07d4dc8e9209d8f39a8ac77e8"

tmp@^0.0.33:
version "0.0.33"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
Expand Down

0 comments on commit d400729

Please sign in to comment.