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

evaluate polished #15540

Closed
wants to merge 3 commits into from
Closed
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
4 changes: 2 additions & 2 deletions docs/src/pages/style/color/ColorTool.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import Typography from '@material-ui/core/Typography';
import Button from '@material-ui/core/Button';
import CheckIcon from '@material-ui/icons/Check';
import Slider from '@material-ui/lab/Slider';
import { rgbToHex } from '@material-ui/core/styles/colorManipulator';
// import { rgbToHex } from '@material-ui/core/styles/colorManipulator';
import { capitalize } from '@material-ui/core/utils/helpers';
import ColorDemo from './ColorDemo';
import themeInitialState from 'docs/src/modules/styles/themeInitialState';
Expand Down Expand Up @@ -171,7 +171,7 @@ class ColorTool extends React.Component {
variant="caption"
style={{ color: theme.palette.getContrastText(background[key]) }}
>
{rgbToHex(background[key])}
{background[key]}
</Typography>
</div>
))}
Expand Down
1 change: 1 addition & 0 deletions packages/material-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"hoist-non-react-statics": "^3.2.1",
"is-plain-object": "^2.0.4",
"normalize-scroll-left": "^0.1.2",
"polished": "^3.2.0",
"popper.js": "^1.14.1",
"prop-types": "^15.7.2",
"react-event-listener": "^0.6.6",
Expand Down
201 changes: 8 additions & 193 deletions packages/material-ui/src/styles/colorManipulator.js
Original file line number Diff line number Diff line change
@@ -1,154 +1,9 @@
/* eslint-disable no-use-before-define */

import warning from 'warning';

/**
* Returns a number whose value is limited to the given range.
*
* @param {number} value The value to be clamped
* @param {number} min The lower boundary of the output range
* @param {number} max The upper boundary of the output range
* @returns {number} A number in the range [min, max]
*/
function clamp(value, min = 0, max = 1) {
warning(
value >= min && value <= max,
`Material-UI: the value provided ${value} is out of range [${min}, ${max}].`,
);

if (value < min) {
return min;
}
if (value > max) {
return max;
}
return value;
}

/**
* Converts a color from CSS hex format to CSS rgb format.
*
* @param {string} color - Hex color, i.e. #nnn or #nnnnnn
* @returns {string} A CSS rgb color string
*/
export function hexToRgb(color) {
color = color.substr(1);

const re = new RegExp(`.{1,${color.length / 3}}`, 'g');
let colors = color.match(re);

if (colors && colors[0].length === 1) {
colors = colors.map(n => n + n);
}

return colors ? `rgb(${colors.map(n => parseInt(n, 16)).join(', ')})` : '';
}

function intToHex(int) {
const hex = int.toString(16);
return hex.length === 1 ? `0${hex}` : hex;
}

/**
* Converts a color from CSS rgb format to CSS hex format.
*
* @param {string} color - RGB color, i.e. rgb(n, n, n)
* @returns {string} A CSS rgb color string, i.e. #nnnnnn
*/
export function rgbToHex(color) {
// Idempotent
if (color.indexOf('#') === 0) {
return color;
}

const { values } = decomposeColor(color);
return `#${values.map(n => intToHex(n)).join('')}`;
}

/**
* Converts a color from hsl format to rgb format.
*
* @param {string} color - HSL color values
* @returns {string} rgb color values
*/
export function hslToRgb(color) {
color = decomposeColor(color);
const { values } = color;
const h = values[0];
const s = values[1] / 100;
const l = values[2] / 100;
const a = s * Math.min(l, 1 - l);
const f = (n, k = (n + h / 30) % 12) => l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);

let type = 'rgb';
const rgb = [Math.round(f(0) * 255), Math.round(f(8) * 255), Math.round(f(4) * 255)];

if (color.type === 'hsla') {
type += 'a';
rgb.push(values[3]);
}

return recomposeColor({ type, values: rgb });
}

/**
* Returns an object with the type and values of a color.
*
* Note: Does not support rgb % values.
*
* @param {string} color - CSS color, i.e. one of: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla()
* @returns {object} - A MUI color object: {type: string, values: number[]}
*/
export function decomposeColor(color) {
// Idempotent
if (color.type) {
return color;
}

if (color.charAt(0) === '#') {
return decomposeColor(hexToRgb(color));
}

const marker = color.indexOf('(');
const type = color.substring(0, marker);

if (['rgb', 'rgba', 'hsl', 'hsla'].indexOf(type) === -1) {
throw new Error(
[
`Material-UI: unsupported \`${color}\` color.`,
'We support the following formats: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla().',
].join('\n'),
);
}

let values = color.substring(marker + 1, color.length - 1).split(',');
values = values.map(value => parseFloat(value));

return { type, values };
}

/**
* Converts a color object with type and values to a string.
*
* @param {object} color - Decomposed color
* @param {string} color.type - One of: 'rgb', 'rgba', 'hsl', 'hsla'
* @param {array} color.values - [n,n,n] or [n,n,n,n]
* @returns {string} A CSS color string
*/
export function recomposeColor(color) {
const { type } = color;
let { values } = color;

if (type.indexOf('rgb') !== -1) {
// Only convert the first 3 values to int (i.e. not alpha)
values = values.map((n, i) => (i < 3 ? parseInt(n, 10) : n));
} else if (type.indexOf('hsl') !== -1) {
values[1] = `${values[1]}%`;
values[2] = `${values[2]}%`;
}

return `${type}(${values.join(', ')})`;
}
import lighten2 from 'polished/lib/color/lighten';
import darken2 from 'polished/lib/color/darken';
import rgba from 'polished/lib/color/rgba';
import getLuminance from 'polished/lib/color/getLuminance';

/**
* Calculates the contrast ratio between two colors.
Expand All @@ -174,18 +29,7 @@ export function getContrastRatio(foreground, background) {
* @param {string} color - CSS color, i.e. one of: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla()
* @returns {number} The relative brightness of the color in the range 0 - 1
*/
export function getLuminance(color) {
color = decomposeColor(color);

let rgb = color.type === 'hsl' ? decomposeColor(hslToRgb(color)).values : color.values;
rgb = rgb.map(val => {
val /= 255; // normalized
return val <= 0.03928 ? val / 12.92 : ((val + 0.055) / 1.055) ** 2.4;
});

// Truncate at 3 digits
return Number((0.2126 * rgb[0] + 0.7152 * rgb[1] + 0.0722 * rgb[2]).toFixed(3));
}
export { getLuminance };

/**
* Darken or lighten a color, depending on its luminance.
Expand All @@ -208,15 +52,7 @@ export function emphasize(color, coefficient = 0.15) {
* @returns {string} A CSS color string. Hex input values are returned as rgb
*/
export function fade(color, value) {
color = decomposeColor(color);
value = clamp(value);

if (color.type === 'rgb' || color.type === 'hsl') {
color.type += 'a';
}
color.values[3] = value;

return recomposeColor(color);
return rgba(color, value);
}

/**
Expand All @@ -227,17 +63,7 @@ export function fade(color, value) {
* @returns {string} A CSS color string. Hex input values are returned as rgb
*/
export function darken(color, coefficient) {
color = decomposeColor(color);
coefficient = clamp(coefficient);

if (color.type.indexOf('hsl') !== -1) {
color.values[2] *= 1 - coefficient;
} else if (color.type.indexOf('rgb') !== -1) {
for (let i = 0; i < 3; i += 1) {
color.values[i] *= 1 - coefficient;
}
}
return recomposeColor(color);
return darken2(coefficient, color);
}

/**
Expand All @@ -248,16 +74,5 @@ export function darken(color, coefficient) {
* @returns {string} A CSS color string. Hex input values are returned as rgb
*/
export function lighten(color, coefficient) {
color = decomposeColor(color);
coefficient = clamp(coefficient);

if (color.type.indexOf('hsl') !== -1) {
color.values[2] += (100 - color.values[2]) * coefficient;
} else if (color.type.indexOf('rgb') !== -1) {
for (let i = 0; i < 3; i += 1) {
color.values[i] += (255 - color.values[i]) * coefficient;
}
}

return recomposeColor(color);
return lighten2(coefficient, color);
}
Loading