ngx-input-color
Version:
Angular color input component and color picker (with HSL, HSV, RGB, CMYK, HEX, alpha, eye-dropper, etc)
110 lines • 14.3 kB
JavaScript
export function buildGradientFromStops(stops, type = 'linear', rotation = 0) {
if (!stops || stops.length === 0)
return '';
const sorted = [...stops].sort((a, b) => a.value - b.value);
const parts = [];
for (const stop of sorted) {
const value = Math.max(0, Math.min(stop.value, 100));
parts.push(`${stop.color} ${value}%`);
}
let f = '';
if (type === 'linear') {
f = `${rotation}deg, `;
}
else {
f = 'circle, ';
}
return `${type}-gradient(${f}${parts.join(', ')})`;
}
export function generateRandomColor() {
const letters = '0123456789ABCDEF';
let color = '#';
for (let i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
export function isValidGradient(value) {
// Accepts linear-gradient or radial-gradient with any color format
return /^(\s*)(linear|radial)-gradient\s*\(/i.test(value);
}
export function parseGradient(value) {
let type = 'linear';
let rotation = 90;
let stops = [];
let valid = false;
let match = value.match(/^(\s*)(linear|radial)-gradient\s*\((.*)\)$/i);
if (!match)
return { type, rotation, stops, valid };
type = match[2];
let content = match[3];
// Split by commas, but ignore commas inside parentheses (for rgb, hsl, etc)
let parts = [];
let buf = '', depth = 0;
for (let c of content) {
if (c === '(')
depth++;
if (c === ')')
depth--;
if (c === ',' && depth === 0) {
parts.push(buf.trim());
buf = '';
}
else {
buf += c;
}
}
if (buf)
parts.push(buf.trim());
// First part may be angle/direction (for linear) or shape/position (for radial)
let first = parts[0];
let colorStopStart = 0;
if (type === 'linear') {
let angleMatch = first.match(/^(\d+)(deg)?$/i);
if (angleMatch) {
rotation = parseInt(angleMatch[1], 10);
colorStopStart = 1;
}
else if (/to /.test(first)) {
// e.g. 'to right', 'to bottom left' (optional: map to degree)
// You can add mapping if needed
colorStopStart = 1;
}
}
else if (type === 'radial') {
// e.g. 'circle at center', 'ellipse at top left', etc
if (!/^(#|rgb|hsl|[a-z])/i.test(first))
colorStopStart = 1;
}
// Color stop regex: supports hex, rgb(a), hsl(a), color names, with optional position
const colorStopRegex = /((#([0-9a-fA-F]{3,8}))|(rgba?\([^\)]+\))|(hsla?\([^\)]+\))|([a-zA-Z]+))(\s+([\d.]+%?|[\d.]+px|[\d.]+em))?/;
for (let i = colorStopStart; i < parts.length; i++) {
let stopPart = parts[i];
let m = stopPart.match(colorStopRegex);
if (m) {
let color = m[1];
let posStr = m[8];
let value = 0;
if (posStr) {
if (posStr.endsWith('%'))
value = parseFloat(posStr);
else
value = parseFloat(posStr); // px/em: you may want to normalize or keep as is
}
else {
value = i === colorStopStart ? 0 : 100;
}
stops.push({ color, value, id: generateId(stops) });
}
}
valid = stops.length >= 2;
return { type, rotation, stops, valid };
}
function generateId(rangeValues) {
let id = 'ngx-thumb-' + Math.random().toString(36).substring(2, 9);
if (rangeValues.findIndex((x) => x.id == id) >= 0) {
return generateId(rangeValues);
}
return id;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGQtZ3JhZGllbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtaW5wdXQtY29sb3Ivc3JjL3V0aWxzL2J1aWxkLWdyYWRpZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE1BQU0sVUFBVSxzQkFBc0IsQ0FBQyxLQUFxQixFQUFFLE9BQXFCLFFBQVEsRUFBRSxRQUFRLEdBQUcsQ0FBQztJQUN2RyxJQUFJLENBQUMsS0FBSyxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQztRQUFFLE9BQU8sRUFBRSxDQUFDO0lBRTVDLE1BQU0sTUFBTSxHQUFHLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUU1RCxNQUFNLEtBQUssR0FBYSxFQUFFLENBQUM7SUFFM0IsS0FBSyxNQUFNLElBQUksSUFBSSxNQUFNLEVBQUUsQ0FBQztRQUMxQixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNyRCxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO0lBQ3hDLENBQUM7SUFFRCxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7SUFDWCxJQUFJLElBQUksS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUN0QixDQUFDLEdBQUcsR0FBRyxRQUFRLE9BQU8sQ0FBQztJQUN6QixDQUFDO1NBQU0sQ0FBQztRQUNOLENBQUMsR0FBRyxVQUFVLENBQUM7SUFDakIsQ0FBQztJQUVELE9BQU8sR0FBRyxJQUFJLGFBQWEsQ0FBQyxHQUFHLEtBQUssQ0FB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QztJQUMxQixPQUFPLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLENBQUM7QUFDMUMsQ0FBQztBQUNELFNBQVMsVUFBVSxDQUFDLFdBQTJCO0lBQzdDLElBQUksRUFBRSxHQUFHLFlBQVksR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDbkUsSUFBSSxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQ2xELE9BQU8sVUFBVSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ2pDLENBQUM7SUFDRCxPQUFPLEVBQUUsQ0FBQztBQUNaLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBHcmFkaWVudFN0b3AsIEdyYWRpZW50VHlwZSB9IGZyb20gJy4uL21vZGVscy9HcmFkaWVudFN0b3AnO1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkR3JhZGllbnRGcm9tU3RvcHMoc3RvcHM6IEdyYWRpZW50U3RvcFtdLCB0eXBlOiBHcmFkaWVudFR5cGUgPSAnbGluZWFyJywgcm90YXRpb24gPSAwKTogc3RyaW5nIHtcclxuICBpZiAoIXN0b3BzIHx8IHN0b3BzLmxlbmd0aCA9PT0gMCkgcmV0dXJuICcnO1xyXG5cclxuICBjb25zdCBzb3J0ZWQgPSBbLi4uc3RvcHNdLnNvcnQoKGEsIGIpID0+IGEudmFsdWUgLSBiLnZhbHVlKTtcclxuXHJcbiAgY29uc3QgcGFydHM6IHN0cmluZ1tdID0gW107XHJcblxyXG4gIGZvciAoY29uc3Qgc3RvcCBvZiBzb3J0ZWQpIHtcclxuICAgIGNvbnN0IHZhbHVlID0gTWF0aC5tYXgoMCwgTWF0aC5taW4oc3RvcC52YWx1ZSwgMTAwKSk7XHJcbiAgICBwYXJ0cy5wdXNoKGAke3N0b3AuY29sb3J9ICR7dmFsdWV9JWApO1xyXG4gIH1cclxuXHJcbiAgbGV0IGYgPSAnJztcclxuICBpZiAodHlwZSA9PT0gJ2xpbmVhcicpIHtcclxuICAgIGYgPSBgJHtyb3RhdGlvbn1kZWcsIGA7XHJcbiAgfSBlbHNlIHtcclxuICAgIGYgPSAnY2lyY2xlLCAnO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIGAke3R5cGV9LWdyYWRpZW50KCR7Zn0ke3BhcnRzLmpvaW4oJywgJyl9KWA7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZVJhbmRvbUNvbG9yKCk6IHN0cmluZyB7XHJcbiAgY29uc3QgbGV0dGVycyA9ICcwMTIzNDU2Nzg5QUJDREVGJztcclxuICBsZXQgY29sb3IgPSAnIyc7XHJcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCA2OyBpKyspIHtcclxuICAgIGNvbG9yICs9IGxldHRlcnNbTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMTYpXTtcclxuICB9XHJcbiAgcmV0dXJuIGNvbG9yO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gaXNWYWxpZEdyYWRpZW50KHZhbHVlOiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAvLyBBY2NlcHRzIGxpbmVhci1ncmFkaWVudCBvciByYWRpYWwtZ3JhZGllbnQgd2l0aCBhbnkgY29sb3IgZm9ybWF0XHJcbiAgcmV0dXJuIC9eKFxccyopKGxpbmVhcnxyYWRpYWwpLWdyYWRpZW50XFxzKlxcKC9pLnRlc3QodmFsdWUpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VHcmFkaWVudCh2YWx1ZTogc3RyaW5nKToge1xyXG4gIHR5cGU6IEdyYWRpZW50VHlwZTtcclxuICByb3RhdGlvbjogbnVtYmVyO1xyXG4gIHN0b3BzOiBHcmFkaWVudFN0b3BbXTtcclxuICB2YWxpZDogYm9vbGVhbjtcclxufSB7XHJcbiAgbGV0IHR5cGU6IEdyYWRpZW50VHlwZSA9ICdsaW5lYXInO1xyXG4gIGxldCByb3RhdGlvbiA9IDkwO1xyXG4gIGxldCBzdG9wczogR3JhZGllbnRTdG9wW10gPSBbXTtcclxuICBsZXQgdmFsaWQgPSBmYWxzZTtcclxuICBsZXQgbWF0Y2ggPSB2YWx1ZS5tYXRjaCgvXihcXHMqKShsaW5lYXJ8cmFkaWFsKS1ncmFkaWVudFxccypcXCgoLiopXFwpJC9pKTtcclxuICBpZiAoIW1hdGNoKSByZXR1cm4geyB0eXBlLCByb3RhdGlvbiwgc3RvcHMsIHZhbGlkIH07XHJcbiAgdHlwZSA9IG1hdGNoWzJdIGFzIEdyYWRpZW50VHlwZTtcclxuICBsZXQgY29udGVudCA9IG1hdGNoWzNdO1xyXG4gIC8vIFNwbGl0IGJ5IGNvbW1hcywgYnV0IGlnbm9yZSBjb21tYXMgaW5zaWRlIHBhcmVudGhlc2VzIChmb3IgcmdiLCBoc2wsIGV0YylcclxuICBsZXQgcGFydHMgPSBbXTtcclxuICBsZXQgYnVmID0gJycsXHJcbiAgICBkZXB0aCA9IDA7XHJcbiAgZm9yIChsZXQgYyBvZiBjb250ZW50KSB7XHJcbiAgICBpZiAoYyA9PT0gJygnKSBkZXB0aCsrO1xyXG4gICAgaWYgKGMgPT09ICcpJykgZGVwdGgtLTtcclxuICAgIGlmIChjID09PSAnLCcgJiYgZGVwdGggPT09IDApIHtcclxuICAgICAgcGFydHMucHVzaChidWYudHJpbSgpKTtcclxuICAgICAgYnVmID0gJyc7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBidWYgKz0gYztcclxuICAgIH1cclxuICB9XHJcbiAgaWYgKGJ1ZikgcGFydHMucHVzaChidWYudHJpbSgpKTtcclxuICAvLyBGaXJzdCBwYXJ0IG1heSBiZSBhbmdsZS9kaXJlY3Rpb24gKGZvciBsaW5lYXIpIG9yIHNoYXBlL3Bvc2l0aW9uIChmb3IgcmFkaWFsKVxyXG4gIGxldCBmaXJzdCA9IHBhcnRzWzBdO1xyXG4gIGxldCBjb2xvclN0b3BTdGFydCA9IDA7XHJcbiAgaWYgKHR5cGUgPT09ICdsaW5lYXInKSB7XHJcbiAgICBsZXQgYW5nbGVNYXRjaCA9IGZpcnN0Lm1hdGNoKC9eKFxcZCspKGRlZyk/JC9pKTtcclxuICAgIGlmIChhbmdsZU1hdGNoKSB7XHJcbiAgICAgIHJvdGF0aW9uID0gcGFyc2VJbnQoYW5nbGVNYXRjaFsxXSwgMTApO1xyXG4gICAgICBjb2xvclN0b3BTdGFydCA9IDE7XHJcbiAgICB9IGVsc2UgaWYgKC90byAvLnRlc3QoZmlyc3QpKSB7XHJcbiAgICAgIC8vIGUuZy4gJ3RvIHJpZ2h0JywgJ3RvIGJvdHRvbSBsZWZ0JyAob3B0aW9uYWw6IG1hcCB0byBkZWdyZWUpXHJcbiAgICAgIC8vIFlvdSBjYW4gYWRkIG1hcHBpbmcgaWYgbmVlZGVkXHJcbiAgICAgIGNvbG9yU3RvcFN0YXJ0ID0gMTtcclxuICAgIH1cclxuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdyYWRpYWwnKSB7XHJcbiAgICAvLyBlLmcuICdjaXJjbGUgYXQgY2VudGVyJywgJ2VsbGlwc2UgYXQgdG9wIGxlZnQnLCBldGNcclxuICAgIGlmICghL14oI3xyZ2J8aHNsfFthLXpdKS9pLnRlc3QoZmlyc3QpKSBjb2xvclN0b3BTdGFydCA9IDE7XHJcbiAgfVxyXG4gIC8vIENvbG9yIHN0b3AgcmVnZXg6IHN1cHBvcnRzIGhleCwgcmdiKGEpLCBoc2woYSksIGNvbG9yIG5hbWVzLCB3aXRoIG9wdGlvbmFsIHBvc2l0aW9uXHJcbiAgY29uc3QgY29sb3JTdG9wUmVnZXggPVxyXG4gICAgLygoIyhbMC05YS1mQS1GXXszLDh9KSl8KHJnYmE/XFwoW15cXCldK1xcKSl8KGhzbGE/XFwoW15cXCldK1xcKSl8KFthLXpBLVpdKykpKFxccysoW1xcZC5dKyU/fFtcXGQuXStweHxbXFxkLl0rZW0pKT8vO1xyXG4gIGZvciAobGV0IGkgPSBjb2xvclN0b3BTdGFydDsgaSA8IHBhcnRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICBsZXQgc3RvcFBhcnQgPSBwYXJ0c1tpXTtcclxuICAgIGxldCBtID0gc3RvcFBhcnQubWF0Y2goY29sb3JTdG9wUmVnZXgpO1xyXG4gICAgaWYgKG0pIHtcclxuICAgICAgbGV0IGNvbG9yID0gbVsxXTtcclxuICAgICAgbGV0IHBvc1N0ciA9IG1bOF07XHJcbiAgICAgIGxldCB2YWx1ZSA9IDA7XHJcbiAgICAgIGlmIChwb3NTdHIpIHtcclxuICAgICAgICBpZiAocG9zU3RyLmVuZHNXaXRoKCclJykpIHZhbHVlID0gcGFyc2VGbG9hdChwb3NTdHIpO1xyXG4gICAgICAgIGVsc2UgdmFsdWUgPSBwYXJzZUZsb2F0KHBvc1N0cik7IC8vIHB4L2VtOiB5b3UgbWF5IHdhbnQgdG8gbm9ybWFsaXplIG9yIGtlZXAgYXMgaXNcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB2YWx1ZSA9IGkgPT09IGNvbG9yU3RvcFN0YXJ0ID8gMCA6IDEwMDtcclxuICAgICAgfVxyXG4gICAgICBzdG9wcy5wdXNoKHsgY29sb3IsIHZhbHVlLCBpZDogZ2VuZXJhdGVJZChzdG9wcykgfSk7XHJcbiAgICB9XHJcbiAgfVxyXG4gIHZhbGlkID0gc3RvcHMubGVuZ3RoID49IDI7XHJcbiAgcmV0dXJuIHsgdHlwZSwgcm90YXRpb24sIHN0b3BzLCB2YWxpZCB9O1xyXG59XHJcbmZ1bmN0aW9uIGdlbmVyYXRlSWQocmFuZ2VWYWx1ZXM6IEdyYWRpZW50U3RvcFtdKTogc3RyaW5nIHtcclxuICBsZXQgaWQgPSAnbmd4LXRodW1iLScgKyBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zdWJzdHJpbmcoMiwgOSk7XHJcbiAgaWYgKHJhbmdlVmFsdWVzLmZpbmRJbmRleCgoeCkgPT4geC5pZCA9PSBpZCkgPj0gMCkge1xyXG4gICAgcmV0dXJuIGdlbmVyYXRlSWQocmFuZ2VWYWx1ZXMpO1xyXG4gIH1cclxuICByZXR1cm4gaWQ7XHJcbn1cclxuIl19