Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions UNRELEASED.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Use [the changelog guidelines](https://git.io/polaris-changelog-guidelines) to f
### Enhancements

- Add `variableHeight` prop to `DropZone` so children control its height ([#4136](https://github.com/Shopify/polaris-react/pull/4136))
- Add `fullWidth` prop to `ColorPicker` so the color picker can take the full width ([#4152](https://github.com/Shopify/polaris-react/pull/4152))

### Bug fixes

Expand Down
5 changes: 5 additions & 0 deletions src/components/ColorPicker/ColorPicker.scss
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ $stacking-order: (
height: $picker-size;
width: $picker-size;

.fullWidth & {
width: auto;
flex-grow: 1;
}

// Need an extra pixel to avoid a small color bleed from happening
border-radius: var(--p-border-radius-base);
cursor: pointer;
Expand Down
52 changes: 38 additions & 14 deletions src/components/ColorPicker/ColorPicker.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import React, {PureComponent} from 'react';

import {clamp} from '../../utilities/clamp';
import {classNames} from '../../utilities/css';
import {hsbToRgb} from '../../utilities/color-transformers';
import type {HSBColor, HSBAColor} from '../../utilities/color-types';

import {AlphaPicker, HuePicker, Slidable, SlidableProps} from './components';
import styles from './ColorPicker.scss';

interface State {
pickerSize: number;
pickerSize: {
width: number;
height: number;
};
}

interface Color extends HSBColor {
Expand All @@ -23,13 +27,18 @@ export interface ColorPickerProps {
color: Color;
/** Allow user to select an alpha value */
allowAlpha?: boolean;
/** Allow HuePicker to take the full width */
fullWidth?: boolean;
/** Callback when color is selected */
onChange(color: HSBAColor): void;
}

export class ColorPicker extends PureComponent<ColorPickerProps, State> {
state: State = {
pickerSize: 0,
pickerSize: {
width: 0,
height: 0,
},
};

private colorNode: HTMLElement | null = null;
Expand All @@ -40,25 +49,39 @@ export class ColorPicker extends PureComponent<ColorPickerProps, State> {
return;
}

this.setState({pickerSize: colorNode.clientWidth});
this.setState({
pickerSize: {
width: colorNode.clientWidth,
height: colorNode.clientHeight,
},
});

if (process.env.NODE_ENV === 'development') {
setTimeout(() => {
this.setState({pickerSize: colorNode.clientWidth});
this.setState({
pickerSize: {
width: colorNode.clientWidth,
height: colorNode.clientHeight,
},
});
}, 0);
}
}

render() {
const {id, color, allowAlpha} = this.props;
const {id, color, allowAlpha, fullWidth} = this.props;
const {hue, saturation, brightness, alpha: providedAlpha} = color;
const {pickerSize} = this.state;

const alpha = providedAlpha != null && allowAlpha ? providedAlpha : 1;
const {red, green, blue} = hsbToRgb({hue, saturation: 1, brightness: 1});
const colorString = `rgba(${red}, ${green}, ${blue}, ${alpha})`;
const draggerX = clamp(saturation * pickerSize, 0, pickerSize);
const draggerY = clamp(pickerSize - brightness * pickerSize, 0, pickerSize);
const draggerX = clamp(saturation * pickerSize.width, 0, pickerSize.width);
const draggerY = clamp(
pickerSize.height - brightness * pickerSize.height,
0,
pickerSize.height,
);

const alphaSliderMarkup = allowAlpha ? (
<AlphaPicker
Expand All @@ -68,12 +91,13 @@ export class ColorPicker extends PureComponent<ColorPickerProps, State> {
/>
) : null;

const className = classNames(
styles.ColorPicker,
fullWidth && styles.fullWidth,
);

return (
<div
className={styles.ColorPicker}
id={id}
onMouseDown={this.handlePickerDrag}
>
<div className={className} id={id} onMouseDown={this.handlePickerDrag}>
<div ref={this.setColorNode} className={styles.MainColor}>
<div
className={styles.ColorLayer}
Expand Down Expand Up @@ -118,8 +142,8 @@ export class ColorPicker extends PureComponent<ColorPickerProps, State> {
onChange,
} = this.props;

const saturation = clamp(x / pickerSize, 0, 1);
const brightness = clamp(1 - y / pickerSize, 0, 1);
const saturation = clamp(x / pickerSize.width, 0, 1);
const brightness = clamp(1 - y / pickerSize.height, 0, 1);

onChange({hue, saturation, brightness, alpha});
};
Expand Down
24 changes: 19 additions & 5 deletions src/components/ColorPicker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,7 @@ function ColorPickerExample() {
saturation: 1,
});

const handleChange = useCallback(setColor, []);

return <ColorPicker onChange={handleChange} color={color} />;
return <ColorPicker onChange={setColor} color={color} />;
}
```

Expand All @@ -65,8 +63,24 @@ function ColorPickerWithTransparentValueExample() {
alpha: 0.7,
});

const handleChange = useCallback(setColor, []);
return <ColorPicker onChange={setColor} color={color} allowAlpha />;
}
```

### Colorpicker with transparent value full width

Use when attached to a visual builder to allow the designated object to have a
transparent background that allows underlying objects to show through.

```jsx
function ColorPickerWithTransparentValueExample() {
const [color, setColor] = useState({
hue: 300,
brightness: 1,
saturation: 0.7,
alpha: 0.7,
});

return <ColorPicker onChange={handleChange} color={color} allowAlpha />;
return <ColorPicker fullWidth onChange={setColor} color={color} allowAlpha />;
}
```