react-iro-gradient-picker 1.2.1 → 1.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -6394,111 +6394,147 @@ var isValidRgba = (function (rgba) {
6394
6394
  return !!rgbaToHex(rgba);
6395
6395
  });
6396
6396
 
6397
- var combineRegExp = function (regexpList, flags) {
6398
- return new RegExp(regexpList.reduce(function (result, item) {
6399
- return result + (typeof item === 'string' ? item : item.source);
6400
- }, ''), flags);
6401
- };
6402
- var generateRegExp = function () {
6403
- var searchFlags = 'gi';
6404
- var rAngle = /(?:[+-]?\d*\.?\d+)(?:deg|grad|rad|turn)/;
6405
- var rSideCornerCapture = /to\s+((?:(?:left|right)(?:\s+(?:top|bottom))?))/;
6406
- var rRadial = /circle at\s+((?:(?:left|right|center|top|bottom)(?:\s+(?:left|right|center|top|bottom))?))/;
6407
- var rComma = /\s*,\s*/;
6408
- var rColorHex = /\#(?:[a-f0-9]{6,8}|[a-f0-9]{3})/;
6409
- var rDigits3 = /\(\s*(?:\d{1,3}%?\s*,\s*){2}%?\d{1,3}%?\s*\)/;
6410
- var rDigits4 = /\(\s*(?:\d{1,3}%?\s*,\s*){2}%?\d{1,3}%?\s*,\s*\d*\.?\d+\)/;
6411
- var rValue = /(?:[+-]?\d*\.?\d+)(?:%|[a-z]+)?/;
6412
- var rKeyword = /[_a-z-][_a-z0-9-]*/;
6413
- var rColor = combineRegExp([
6414
- '(?:',
6415
- rColorHex,
6416
- '|',
6417
- '(?:rgb|hsl)',
6418
- rDigits3,
6419
- '|',
6420
- '(?:rgba|hsla)',
6421
- rDigits4,
6422
- '|',
6423
- rKeyword,
6424
- ')'
6425
- ], '');
6426
- var rColorStop = combineRegExp([rColor, '(?:\\s+', rValue, '(?:\\s+', rValue, ')?)?'], '');
6427
- var rColorStopList = combineRegExp(['(?:', rColorStop, rComma, ')*', rColorStop], '');
6428
- var rLineCapture = combineRegExp(['(?:(', rAngle, ')|', rSideCornerCapture, '|', rRadial, ')'], '');
6429
- var rGradientSearch = combineRegExp(['(?:(', rLineCapture, ')', rComma, ')?(', rColorStopList, ')'], searchFlags);
6430
- var rColorStopSearch = combineRegExp([
6431
- '\\s*(',
6432
- rColor,
6433
- ')',
6434
- '(?:\\s+',
6435
- '(',
6436
- rValue,
6437
- '))?',
6438
- '(?:',
6439
- rComma,
6440
- '\\s*)?'
6441
- ], searchFlags);
6442
- return {
6443
- gradientSearch: rGradientSearch,
6444
- colorStopSearch: rColorStopSearch
6445
- };
6446
- };
6447
- var parseGradient$1 = function (regExpLib, input) {
6448
- var result = {
6449
- stops: [],
6450
- angle: '',
6451
- line: '',
6452
- original: ''
6453
- };
6454
- var matchGradient, matchColorStop, stopResult;
6455
- regExpLib.gradientSearch.lastIndex = 0;
6456
- matchGradient = regExpLib.gradientSearch.exec(input);
6457
- if (matchGradient !== null) {
6458
- result = __assign(__assign({}, result), { original: matchGradient[0] });
6459
- if (matchGradient[1]) {
6460
- result.line = matchGradient[1];
6397
+ var validGradient = (function (input) {
6398
+ try {
6399
+ // Clean input
6400
+ var cleanInput = input
6401
+ .trim()
6402
+ .replace(/;$/, '')
6403
+ .replace(/^background-image:\s*/, '');
6404
+ // Extract gradient type and content
6405
+ var gradientMatch = cleanInput.match(/^(linear|radial)-gradient\s*\(\s*(.*)\s*\)$/i);
6406
+ if (!gradientMatch) {
6407
+ return 'Failed to find gradient';
6461
6408
  }
6462
- if (matchGradient[2]) {
6463
- result.angle = matchGradient[2];
6409
+ var _a = __read(gradientMatch, 3), type = _a[1], content = _a[2];
6410
+ var parts = [];
6411
+ var currentPart = '';
6412
+ var parenDepth = 0;
6413
+ var inQuotes = false;
6414
+ // Parse content by splitting on commas, but respect parentheses and quotes
6415
+ for (var i = 0; i < content.length; i++) {
6416
+ var char = content[i];
6417
+ if (char === '"' || char === "'") {
6418
+ inQuotes = !inQuotes;
6419
+ }
6420
+ else if (!inQuotes) {
6421
+ if (char === '(')
6422
+ parenDepth++;
6423
+ else if (char === ')')
6424
+ parenDepth--;
6425
+ else if (char === ',' && parenDepth === 0) {
6426
+ parts.push(currentPart.trim());
6427
+ currentPart = '';
6428
+ continue;
6429
+ }
6430
+ }
6431
+ currentPart += char;
6464
6432
  }
6465
- if (matchGradient[3]) {
6466
- result.sideCorner = matchGradient[3];
6433
+ if (currentPart.trim()) {
6434
+ parts.push(currentPart.trim());
6467
6435
  }
6468
- regExpLib.colorStopSearch.lastIndex = 0;
6469
- matchColorStop = regExpLib.colorStopSearch.exec(matchGradient[5]);
6470
- while (matchColorStop !== null) {
6471
- var tinyColor = tinycolor(matchColorStop[1]);
6472
- stopResult = {
6473
- color: tinyColor.toRgbString()
6474
- };
6475
- if (matchColorStop[2]) {
6476
- stopResult.position = Number((parseInt(matchColorStop[2], 10) / 100).toFixed(2));
6436
+ var angle = '';
6437
+ var line = '';
6438
+ var colorStops = [];
6439
+ // Determine if first part is direction/angle or color stop
6440
+ var firstPart = parts[0];
6441
+ var isDirection = /^\d+deg$/i.test(firstPart) ||
6442
+ /^to\s+/.test(firstPart) ||
6443
+ /^(?:circle|ellipse)/.test(firstPart) ||
6444
+ /at\s+/.test(firstPart);
6445
+ if (isDirection) {
6446
+ if (type === 'linear') {
6447
+ if (/^\d+deg$/i.test(firstPart)) {
6448
+ angle = firstPart.replace(/deg$/i, '');
6449
+ }
6450
+ else if (/^to\s+/.test(firstPart)) {
6451
+ line = firstPart;
6452
+ // Convert named directions to angles
6453
+ var directionMap = {
6454
+ 'to top': '0',
6455
+ 'to top right': '45',
6456
+ 'to right': '90',
6457
+ 'to bottom right': '135',
6458
+ 'to bottom': '180',
6459
+ 'to bottom left': '225',
6460
+ 'to left': '270',
6461
+ 'to top left': '315'
6462
+ };
6463
+ angle = directionMap[firstPart] || '0';
6464
+ }
6477
6465
  }
6478
- result.stops.push(stopResult);
6479
- matchColorStop = regExpLib.colorStopSearch.exec(matchGradient[5]);
6466
+ else {
6467
+ line = firstPart;
6468
+ }
6469
+ colorStops = parts.slice(1);
6480
6470
  }
6481
- }
6482
- return result;
6483
- };
6484
- var validGradient = (function (input) {
6485
- var regExpLib = generateRegExp();
6486
- var result;
6487
- var rGradientEnclosedInBrackets = /.*gradient\s*\(((?:\([^\)]*\)|[^\)\(]*)*)\)/;
6488
- var match = rGradientEnclosedInBrackets.exec(input);
6489
- if (match !== null) {
6490
- result = parseGradient$1(regExpLib, match[1]);
6491
- if (result.original.trim() !== match[1].trim()) {
6492
- result.parseWarning = true;
6471
+ else {
6472
+ // No explicit direction, use defaults
6473
+ angle = type === 'linear' ? '180' : '';
6474
+ line = type === 'radial' ? 'circle at center' : '';
6475
+ colorStops = parts;
6493
6476
  }
6494
- if (result.stops.every(function (item) { return item.hasOwnProperty('position'); }) === false) {
6495
- result = 'Not correct position';
6477
+ // Parse color stops
6478
+ var stops_1 = [];
6479
+ for (var i = 0; i < colorStops.length; i++) {
6480
+ var stopString = colorStops[i].trim();
6481
+ // Improved regex to handle various gradient stop formats
6482
+ // Matches: color position%, color position, or just color
6483
+ var stopMatch = stopString.match(/^(.+?)(?:\s+([\d.]+)(%|px|em|rem)?)?$/);
6484
+ if (stopMatch) {
6485
+ var _b = __read(stopMatch, 4), colorStr = _b[1], positionStr = _b[2], unit = _b[3];
6486
+ var tinyColorInstance = tinycolor(colorStr.trim());
6487
+ if (tinyColorInstance.isValid()) {
6488
+ var stop_1 = {
6489
+ color: tinyColorInstance.toRgbString()
6490
+ };
6491
+ if (positionStr) {
6492
+ var position = parseFloat(positionStr);
6493
+ // Convert percentage to decimal (0-1 range)
6494
+ if (unit === '%' || !unit) {
6495
+ // If no unit specified, assume percentage
6496
+ position = position / 100;
6497
+ }
6498
+ stop_1.position = Math.max(0, Math.min(1, position));
6499
+ }
6500
+ stops_1.push(stop_1);
6501
+ }
6502
+ else {
6503
+ console.warn('Invalid color in gradient stop:', colorStr.trim());
6504
+ }
6505
+ }
6506
+ else {
6507
+ console.warn('Could not parse gradient stop:', stopString);
6508
+ }
6509
+ }
6510
+ // Auto-assign positions if missing
6511
+ stops_1.forEach(function (stop, index) {
6512
+ if (!stop.hasOwnProperty('position')) {
6513
+ stop.position = stops_1.length > 1 ? index / (stops_1.length - 1) : 0;
6514
+ }
6515
+ });
6516
+ // Ensure we have at least 2 stops
6517
+ if (stops_1.length === 0) {
6518
+ return 'No valid color stops found';
6496
6519
  }
6520
+ else if (stops_1.length === 1) {
6521
+ // Duplicate the single stop to create a valid gradient
6522
+ stops_1.push({
6523
+ color: stops_1[0].color,
6524
+ position: 1
6525
+ });
6526
+ }
6527
+ return {
6528
+ stops: stops_1,
6529
+ angle: angle,
6530
+ line: line,
6531
+ original: cleanInput
6532
+ };
6497
6533
  }
6498
- else {
6499
- result = 'Failed to find gradient';
6534
+ catch (error) {
6535
+ console.warn('Error parsing gradient:', error);
6536
+ return 'Failed to parse gradient';
6500
6537
  }
6501
- return result;
6502
6538
  });
6503
6539
 
6504
6540
  var LINEAR_POS = [
@@ -6566,7 +6602,7 @@ var parseGradient = (function (str) {
6566
6602
  var helperAngle = type === 'linear' ? '180' : 'circle at center';
6567
6603
  var modifier = findF || angle_1 || helperAngle;
6568
6604
  return {
6569
- gradient: "".concat(type, "-gradient(").concat(typeof gradient !== 'string' ? gradient.original : str, ")"),
6605
+ gradient: typeof gradient !== 'string' ? gradient.original : str,
6570
6606
  type: type,
6571
6607
  modifier: modifier.match(/\d+/) !== null
6572
6608
  ? Number((_b = modifier.match(/\d+/)) === null || _b === void 0 ? void 0 : _b.join(''))
@@ -6583,7 +6619,7 @@ var parseGradient = (function (str) {
6583
6619
  });
6584
6620
 
6585
6621
  /**
6586
- * Convert gradient object to CSS gradient string
6622
+ * Convert gradient object to CSS gradient string (strict typing)
6587
6623
  */
6588
6624
  function gradientObjectToCss(gradientData) {
6589
6625
  var type = gradientData.type, _a = gradientData.angle, angle = _a === void 0 ? 90 : _a, stops = gradientData.stops;
@@ -6602,6 +6638,38 @@ function gradientObjectToCss(gradientData) {
6602
6638
  return "radial-gradient(circle, ".concat(cssStops, ")");
6603
6639
  }
6604
6640
  }
6641
+ /**
6642
+ * Convert flexible gradient object to CSS gradient string (loose typing)
6643
+ */
6644
+ function flexibleGradientToCss(gradientData) {
6645
+ var _a = gradientData.type, type = _a === void 0 ? 'linear' : _a, angle = gradientData.angle, direction = gradientData.direction, position = gradientData.position, stops = gradientData.stops;
6646
+ // Convert stops to CSS format with flexible position handling
6647
+ var cssStops = stops
6648
+ .map(function (stop) {
6649
+ var color = tinycolor(stop.color);
6650
+ var positionStr = '';
6651
+ if (stop.position !== undefined) {
6652
+ if (typeof stop.position === 'string') {
6653
+ positionStr = " ".concat(stop.position);
6654
+ }
6655
+ else {
6656
+ positionStr = " ".concat(stop.position, "%");
6657
+ }
6658
+ }
6659
+ return "".concat(color.toRgbString()).concat(positionStr);
6660
+ })
6661
+ .join(', ');
6662
+ if (type === 'linear') {
6663
+ // Use direction if provided, otherwise use angle
6664
+ var gradientDirection = direction || (angle ? "".concat(angle, "deg") : '90deg');
6665
+ return "linear-gradient(".concat(gradientDirection, ", ").concat(cssStops, ")");
6666
+ }
6667
+ else {
6668
+ // Handle radial gradients with flexible positioning
6669
+ var radialPosition = position || 'circle';
6670
+ return "radial-gradient(".concat(radialPosition, ", ").concat(cssStops, ")");
6671
+ }
6672
+ }
6605
6673
  /**
6606
6674
  * Convert CSS gradient string to gradient object
6607
6675
  */
@@ -7191,9 +7259,22 @@ var DefaultColorPanel = function (_a) {
7191
7259
  var _d = __read(React.useState([]), 2), formatedDefColors = _d[0], setFormatedDefColors = _d[1];
7192
7260
  React.useEffect(function () {
7193
7261
  if (colorType === 'gradient') {
7194
- setFormatedDefColors(checkValidColorsArray(defaultColors, 'grad').map(function (item) {
7195
- return parseGradient(item);
7196
- }));
7262
+ var validGradients = checkValidColorsArray(defaultColors, 'grad');
7263
+ // For popular colors display, create minimal IColor objects using original CSS strings
7264
+ // This avoids complex parsing issues while still providing functional display
7265
+ var displayGradients = validGradients.map(function (gradientString) {
7266
+ return {
7267
+ gradient: gradientString, // Use the original CSS string directly for display
7268
+ type: gradientString.startsWith('radial-') ? 'radial' : 'linear',
7269
+ modifier: 180, // Default value, not critical for display
7270
+ stops: [
7271
+ // Dummy stops that help identify display objects in onChooseColor
7272
+ ['rgba(255, 0, 0, 1)', 0, 0],
7273
+ ['rgba(0, 255, 0, 1)', 1, 1]
7274
+ ]
7275
+ };
7276
+ });
7277
+ setFormatedDefColors(displayGradients);
7197
7278
  }
7198
7279
  else {
7199
7280
  setFormatedDefColors(checkValidColorsArray(defaultColors, 'solid'));
@@ -7205,6 +7286,41 @@ var DefaultColorPanel = function (_a) {
7205
7286
  return;
7206
7287
  }
7207
7288
  if (colorType === 'gradient' && typeof item !== 'string') {
7289
+ // If this is a simplified display object (identified by dummy stops), parse the gradient properly
7290
+ if (item.stops.length === 2 &&
7291
+ item.stops[0][0] === 'rgba(255, 0, 0, 1)') {
7292
+ try {
7293
+ var properlyParsed = parseGradient(item.gradient);
7294
+ if (properlyParsed &&
7295
+ properlyParsed.stops &&
7296
+ properlyParsed.stops.length > 0) {
7297
+ var stops_1 = properlyParsed.stops;
7298
+ var lastStop_1 = rgbaToArray(stops_1[stops_1.length - 1][0]);
7299
+ var lastStopLoc_1 = stops_1[stops_1.length - 1][1];
7300
+ var activeStop_1 = rgbaToHex([
7301
+ lastStop_1[0],
7302
+ lastStop_1[1],
7303
+ lastStop_1[2]
7304
+ ]);
7305
+ var activeIdx_1 = stops_1[stops_1.length - 1][2];
7306
+ setInit(false);
7307
+ setColor(properlyParsed);
7308
+ setActiveColor &&
7309
+ setActiveColor({
7310
+ hex: activeStop_1,
7311
+ alpha: Number(Math.round(lastStop_1[3] * 100)),
7312
+ loc: lastStopLoc_1,
7313
+ index: activeIdx_1
7314
+ });
7315
+ setActive(index);
7316
+ return;
7317
+ }
7318
+ }
7319
+ catch (error) {
7320
+ console.warn('Failed to parse popular gradient on click:', item.gradient, error);
7321
+ }
7322
+ }
7323
+ // Normal gradient object processing (fallback)
7208
7324
  var stops = item.stops;
7209
7325
  var lastStop = rgbaToArray(stops[stops.length - 1][0]);
7210
7326
  var lastStopLoc = stops[stops.length - 1][1];
@@ -7739,18 +7855,69 @@ var IroGradient = function (_a) {
7739
7855
  // Store the initial value for reset functionality
7740
7856
  var initialValue = React.useRef(value);
7741
7857
  var parsedColors = React.useCallback(function () {
7742
- return parseGradient(value);
7858
+ try {
7859
+ var parsed = parseGradient(value);
7860
+ // If parsing failed, return fallback gradient
7861
+ if (typeof parsed === 'string') {
7862
+ console.warn('Gradient parsing failed, using fallback:', parsed);
7863
+ var fallback = parseGradient('linear-gradient(90deg, #ffffff 0%, #000000 100%)');
7864
+ // Ensure fallback has valid structure
7865
+ if (fallback && typeof fallback === 'object' && Array.isArray(fallback.stops) && fallback.stops.length > 0) {
7866
+ return fallback;
7867
+ }
7868
+ // Ultimate fallback with guaranteed structure
7869
+ return {
7870
+ stops: [
7871
+ ['rgba(255, 255, 255, 1)', 0, 0],
7872
+ ['rgba(0, 0, 0, 1)', 1, 1]
7873
+ ],
7874
+ gradient: 'linear-gradient(90deg, #ffffff 0%, #000000 100%)',
7875
+ modifier: 90,
7876
+ type: 'linear'
7877
+ };
7878
+ }
7879
+ // Validate parsed result has required structure
7880
+ if (parsed && typeof parsed === 'object' && Array.isArray(parsed.stops) && parsed.stops.length > 0) {
7881
+ return parsed;
7882
+ }
7883
+ // If parsed result is invalid, use ultimate fallback
7884
+ console.warn('Parsed gradient has invalid structure:', parsed);
7885
+ return {
7886
+ stops: [
7887
+ ['rgba(255, 255, 255, 1)', 0, 0],
7888
+ ['rgba(0, 0, 0, 1)', 1, 1]
7889
+ ],
7890
+ gradient: 'linear-gradient(90deg, #ffffff 0%, #000000 100%)',
7891
+ modifier: 90,
7892
+ type: 'linear'
7893
+ };
7894
+ }
7895
+ catch (error) {
7896
+ console.warn('Error parsing gradient, using ultimate fallback:', error);
7897
+ return {
7898
+ stops: [
7899
+ ['rgba(255, 255, 255, 1)', 0, 0],
7900
+ ['rgba(0, 0, 0, 1)', 1, 1]
7901
+ ],
7902
+ gradient: 'linear-gradient(90deg, #ffffff 0%, #000000 100%)',
7903
+ modifier: 90,
7904
+ type: 'linear'
7905
+ };
7906
+ }
7743
7907
  // eslint-disable-next-line react-hooks/exhaustive-deps
7744
7908
  }, [value]);
7745
7909
  var _s = parsedColors(), stops = _s.stops, type = _s.type, modifier = _s.modifier;
7746
- var lastStop = rgbaToArray(stops[stops.length - 1][0]);
7747
- var activeStopIndex = stops.length - 1;
7748
- var activeStop = rgbaToHex([lastStop[0], lastStop[1], lastStop[2]]);
7749
- var activeAlpha = Math.round(lastStop[3] * 100);
7750
7910
  var iroPickerRef = React.useRef(null);
7751
7911
  var containerRef = React.useRef(null);
7752
7912
  var isUpdatingFromGradientStop = React.useRef(false);
7753
7913
  var _t = __read(React.useState(200), 2), pickerWidth = _t[0], setPickerWidth = _t[1];
7914
+ // Safe extraction of stop data with fallbacks
7915
+ var safeStops = Array.isArray(stops) && stops.length > 0 ? stops : [['rgba(255, 255, 255, 1)', 0, 0], ['rgba(0, 0, 0, 1)', 1, 1]];
7916
+ var safeLastStop = rgbaToArray(safeStops[safeStops.length - 1][0]);
7917
+ var safeParsedLastStop = Array.isArray(safeLastStop) && safeLastStop.length >= 4 ? safeLastStop : [255, 255, 255, 1];
7918
+ var activeStopIndex = safeStops.length - 1;
7919
+ var activeStop = rgbaToHex([safeParsedLastStop[0], safeParsedLastStop[1], safeParsedLastStop[2]]);
7920
+ var activeAlpha = Math.round(safeParsedLastStop[3] * 100);
7754
7921
  // Responsive width for IroColorPicker - match solid picker logic
7755
7922
  React.useEffect(function () {
7756
7923
  if (!containerRef.current)
@@ -7793,12 +7960,12 @@ var IroGradient = function (_a) {
7793
7960
  gradient: value,
7794
7961
  type: type,
7795
7962
  modifier: modifier,
7796
- stops: stops
7963
+ stops: safeStops
7797
7964
  }), 2), color = _u[0], setColor = _u[1];
7798
7965
  var _v = __read(React.useState({
7799
7966
  hex: activeStop,
7800
7967
  alpha: activeAlpha,
7801
- loc: stops[activeStopIndex][1],
7968
+ loc: safeStops[activeStopIndex][1],
7802
7969
  index: activeStopIndex
7803
7970
  }), 2), activeColor = _v[0], setActiveColor = _v[1];
7804
7971
  var debounceColor = useDebounce(color, debounceMS);
@@ -8031,11 +8198,11 @@ var IroGradient = function (_a) {
8031
8198
  var handleColorFromPanel = function (newColor) {
8032
8199
  setColor(newColor);
8033
8200
  if (newColor === null || newColor === void 0 ? void 0 : newColor.stops) {
8034
- var lastStop_1 = rgbaToArray(newColor.stops[newColor.stops.length - 1][0]);
8035
- var activeStop_1 = rgbaToHex([lastStop_1[0], lastStop_1[1], lastStop_1[2]]);
8201
+ var lastStop = rgbaToArray(newColor.stops[newColor.stops.length - 1][0]);
8202
+ var activeStop_1 = rgbaToHex([lastStop[0], lastStop[1], lastStop[2]]);
8036
8203
  var newActiveColor = {
8037
8204
  hex: activeStop_1,
8038
- alpha: Math.round(lastStop_1[3] * 100),
8205
+ alpha: Math.round(lastStop[3] * 100),
8039
8206
  loc: newColor.stops[newColor.stops.length - 1][1],
8040
8207
  index: newColor.stops.length - 1
8041
8208
  };
@@ -8496,6 +8663,7 @@ exports.checkFormat = checkFormat;
8496
8663
  exports.cn = cn;
8497
8664
  exports.cssToGradientObject = cssToGradientObject;
8498
8665
  exports["default"] = ColorPicker;
8666
+ exports.flexibleGradientToCss = flexibleGradientToCss;
8499
8667
  exports.getGradient = getGradient;
8500
8668
  exports.getHexAlpha = getHexAlpha;
8501
8669
  exports.gradientObjectToCss = gradientObjectToCss;